package com.gitee.xmhzzz.component.mqtt.client.message;

import com.google.common.collect.Maps;
import org.apache.commons.lang3.RandomStringUtils;

import java.util.Collections;
import java.util.Map;
import java.util.Objects;

/**
 * @ClassName CommonMessage
 * @Description
 * @Author wzq
 * @Date 2024/1/11 11:28
 * @Version 1.0
 */
public abstract class CommonMessage<T extends Message> implements Message {
    protected String sn = RandomStringUtils.randomNumeric(12);
    protected long timestamp = System.currentTimeMillis();
    protected String productId;
    protected String deviceId;
    protected volatile Map<String, Object> headers = Maps.newConcurrentMap();

    protected Map<String, Object> data;

    public CommonMessage() {
    }

    public Map<String, Object> getHeaders() {
        if (Objects.isNull(this.headers)) {
            synchronized(this) {
                if (Objects.isNull(this.headers)) {
                    this.headers = Maps.newConcurrentMap();
                }
            }
        }

        return this.headers;
    }

    public Map<String, Object> getData() {
        return Objects.isNull(this.data) ? Collections.emptyMap() : this.data;
    }

    public final T addHeader(String header, Object value) {
        this.getHeaders().put(header, value);
        return this.castSelf();
    }

    public final T addHeaderIfAbsent(String header, Object value) {
        this.getHeaders().putIfAbsent(header, value);
        return this.castSelf();
    }

    public final T removeHeader(String header) {
        this.getHeaders().remove(header);
        return this.castSelf();
    }

    public T castSelf() {
        return (T) this;
    }

    public String getSn() {
        return this.sn;
    }

    public long getTimestamp() {
        return this.timestamp;
    }

    @Override
    public String getProductId() {
        return productId;
    }

    public String getDeviceId() {
        return this.deviceId;
    }

    public void setSn(String sn) {
        this.sn = sn;
    }

    public void setTimestamp(long timestamp) {
        this.timestamp = timestamp;
    }

    public void setProductId(String productId) {
        this.productId = productId;
    }

    public void setDeviceId(String deviceId) {
        this.deviceId = deviceId;
    }

    public void setHeaders(Map<String, Object> headers) {
        this.headers = headers;
    }

    public void setData(Map<String, Object> data) {
        this.data = data;
    }
}
